#ifndef __MRENDER_QUEUE_H__
#define __MRENDER_QUEUE_H__

#include "3DEDefine.h"


class CMRenderQueueGroup;
class CMRenderable;


// Enumeration of queue groups, by which the application may group queued renderables
// so that they are rendered together with events in between
enum _RenderQueueGroupID
{
	RQ_GROUPID_UNDEFINED = 0 ,
	// Use this queue for objects which must be rendered first e.g. backgrounds
	RQ_GROUPID_BACKGROUND = 1 ,
	// First queue (after backgrounds), used for skyboxes if rendered first
	RQ_GROUPID_SKIES_EARLY = 5 ,
	// terrain
	RQ_GROUPID_TERRAIN = 25 ,
	// The default render queue
	RQ_GROUPID_MAIN = 50 ,

	RQ_GROUPID_PARTICLE_AND_TAIL_EFFECT = 60 ,
	RQ_GROUPID_WIREFRAME_BOUDNDINGBOX = 70 ,

	// Penultimate queue(before overlays), used for skyboxes if rendered last
	RQ_GROUPID_SKIES_LATE = 90 ,
	// Use this queue for objects which must be rendered last e.g. overlays
	RQ_GROUPID_OVERLAY = 95 ,
	// number of render queue id
	RQ_GROUPID_COUNT = 100
};
typedef enum _RenderQueueGroupID RenderQueueGroupID;

#define RENDERABLE_DEFAULT_PRIORITY  100


class CMRenderQueue
{
	//
	// typedef 
	//

public:

	struct _RenderQueueGroupNode
	{
		RenderQueueGroupID   eRenderQueueID;
		CMRenderQueueGroup*  pRenderQueueGroup;

		_RenderQueueGroupNode* pPrev;
		_RenderQueueGroupNode* pNext;

		_RenderQueueGroupNode( void )
		{
			eRenderQueueID    = RQ_GROUPID_UNDEFINED;
			pRenderQueueGroup = NULL;

			pPrev = NULL;
			pNext = NULL;
		}
	};
	typedef struct _RenderQueueGroupNode RenderQueueGroupNode;

public:

	//
	// method 
	//

public:

	// constructor
	CMRenderQueue( void );

	// destructor
	~CMRenderQueue( void );

	// Empty the queue - should only be called by SceneManagers.
	void Clear( void );

	// Add a renderable object to the queue.
	void AddRenderable( CMRenderable* pRenderableObj );
	void AddRenderable( CMRenderable* pRenderableObj , RenderQueueGroupID eGroupID );
	void AddRenderable( CMRenderable* pRenderableObj , RenderQueueGroupID eGroupID , unsigned int  uiPriority );

	// Get a render queue group.
	CMRenderQueueGroup* GetQueueGroup( RenderQueueGroupID eGroupID );

	// Get available render queue
	RenderQueueGroupNode* GetQueueGroups( void );

	//
	// attribute 
	//

protected:

	// render queue groups
	RenderQueueGroupNode* m_pRenderQueueGroups; 
	RenderQueueGroupNode* m_pDefaultRenderQueueGroup;

	// The current default queue group
	RenderQueueGroupID m_eDefaultQueueGroup;

	// The default priority
	unsigned int m_uiDefaultRenderablePriority;

	unsigned int m_countAddRenderable;
};


#endif